// Copyright (c) 2009 Mike Haight, Andy Kipp
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.

#include "Layer.h"

using namespace HandBanana::Game;
using namespace HandBanana::Core;
using namespace HandBanana::Utilities::Xml;
using namespace HandBanana::Utilities;

Layer::Layer()
{
}


std::wstring Layer::Name(void) const
{
    return mName;
}


Tile* Layer::GetTile(int x, int y) const
{
    return NULL;
}


//List<WorldObject^>^ Layer::GetObjects(Coordinates::Rectangle argRectangle)
//{
//    List<WorldObject^>^ objectList = gcnew List<WorldObject^>();
//
//    // TODO: The square size should be a const somewhere
//    int left = (int)(argRectangle.X / 32);
//    int top = (int)(argRectangle.Y / 32);
//    int width = (int)(argRectangle.Width / 32);
//    int height = (int)(argRectangle.Height / 32);
//
//    if (left < 0)
//        left = 0;
//
//    if (top < 0)
//        top = 0;
//
//    if (height < 1)
//        height++;
//
//    if (width < 1)
//        width++;
//
//    for (int x = left; x <= left + width; x++)
//    {
//        for (int y = top; y <= top + height; y++)
//        {
//            Tile^ tile = mMap->GetSquare(x,y);
//            if (tile != nullptr)
//                objectList->Add(tile);
//        }
//    }
//
//    return objectList;
//}

void Layer::LoadMap()
{
    // Log
    Logger::Info(L"Loading Map: \"" + mMapName + L"\".");

    long length, index;
    std::ifstream file;

    // Open File
    file.open(mMapName.c_str(), std::ifstream::in | std::ifstream::binary);
    if (!file.is_open())
        throw std::exception("Error loading Layer: File could not be opened.");

    // Get File Length
    file.seekg(0, std::ios::end);
    length = file.tellg();
    file.seekg(0, std::ios::beg);

    for (index = 0; index < length; index++)
    {
        // Read Byte
        char b = file.get();

        // Calculate X and Y
        int y = (index / mRows);
        int x = (index - (y *  mColumns));

        // Create Tile
        Tile* tile = new Tile();
        tile->Location(Location((float)x * Tile::Width, (float)y * Tile::Height));
        tile->Size(Size((float)Tile::Width, (float)Tile::Height));

        // Insert Tiles
        mTiles.push_back(tile);
    }

}

void Layer::ReadXml(const XmlReader& argReader)
{
    // Log
    Logger::Debug(L"Deserializing Layer.");

    // Create XmlDocument
    XmlDocument* doc = new XmlDocument();

    // Load XmlDocument
    doc->Load(argReader);

    // Get Layer XmlElement
    XmlElement* layerElement = doc->GetDocumentElement();

    // Get Layer XmlElement Attributes
    mName = layerElement->GetAttribute(L"Name")->GetValue();
    mMapName = layerElement->GetAttribute(L"Map")->GetValue();
    mTilesName = layerElement->GetAttribute(L"Tiles")->GetValue();
    mRows = wstrparseint(layerElement->GetAttribute(L"Rows")->GetValue());
    mColumns = wstrparseint(layerElement->GetAttribute(L"Columns")->GetValue());

    // Load Map
    LoadMap();

    // Delete XmlDocument
    SAFE_DELETE(doc);
}

void Layer::WriteXml(const XmlWriter& argWriter)
{

}
